#pragma once

#include <string>
#include <mutex>
#include <fstream>
#include "json.hpp"
#include "log.hpp"

namespace xzt
{
    class ConfigManager
    {
    public:
        // 删除拷贝构造函数和赋值运算符
        ConfigManager(const ConfigManager &) = delete;
        ConfigManager &operator=(const ConfigManager &) = delete;

        // 获取单例实例
        static ConfigManager &getInstance()
        {
            static ConfigManager instance;
            return instance;
        }

        // 获取配置项
        const std::string &getServerIp() const noexcept
        {
            return server_ip_;
        }

        int getServerPort() const noexcept  // 注意这是后端对应的端口
        {
            return server_port_;
        }

        std::string getURL() const noexcept
        {
            static std::string url = "none";
            if (url != "none")
            {
                return url;
            }
            // url == "none"  表示首次调用该函数
            url = "http://" + server_ip_ + ":" + std::to_string(server_port_);
            return url;
        }

    private:
        // 私有构造函数
        ConfigManager()
        {
            try
            {
                loadConfig();
            }
            catch (...)
            {
                // 异常安全：加载失败时使用硬编码默认值
                LOG_ERROR("加载config.json配置失败...");
                server_ip_ = "127.0.0.1";
                server_port_ = 8090;  // 后端默认端口
            }
        }

        void loadConfig()
        {
            static constexpr const char *CONFIG_PATH = "../../frontend/forum/public/config.json";

            std::lock_guard<std::mutex> lock(load_mutex_); // 线程安全保证

            std::ifstream file(CONFIG_PATH);
            if (!file.is_open())
            {
                throw std::runtime_error("Failed to open config file: " + std::string(CONFIG_PATH));
            }

            nlohmann::json config;
            try
            {
                file >> config;
            }
            catch (const nlohmann::json::exception &e)
            {
                throw std::runtime_error("JSON parse error: " + std::string(e.what()));
            }

            // 验证必要字段
            if (!config.contains("server") ||
                !config["server"].contains("ip") ||
                !config["server"].contains("backendPort"))
            {
                throw std::runtime_error("Invalid config format");
            }

            server_ip_ = config["server"]["ip"].get<std::string>();
            server_port_ = config["server"]["backendPort"].get<int>();
        }

        // 成员变量
        std::string server_ip_;
        int server_port_;
        static std::mutex load_mutex_;
    };

    // 静态成员初始化
    std::mutex ConfigManager::load_mutex_;

} // namespace xzt